const cloud = require('wx-server-sdk');
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV });
const db = cloud.database();
const _ = db.command;

/**
 * 批量匹配处理（方案A版）
 * - 不再使用 match_records
 * - 基于 matching_pool 两两配对，直接写入 study_records（共享 matchId）
 * - 成功后从 matching_pool 移除已匹配用户
 */
exports.main = async (event, context) => {
  try {
    const now = new Date();
    let cleanedExpired = 0;
    let totalPicked = 0;
    let matchedCount = 0;

    // 0) 清理已过期的匹配池记录（TTL会自动清理，这里做一次主动兜底）
    const expired = await db.collection('matching_pool')
      .where({ expireAt: _.lt(now) })
      .get();
    if (expired.data && expired.data.length) {
      await Promise.all(expired.data.map(doc => db.collection('matching_pool').doc(doc._id).remove()));
      cleanedExpired = expired.data.length;
      console.log(`清理过期 matching_pool 记录: ${cleanedExpired} 条`);
    }

    // 1) 拉取当前匹配池用户（未过期）
    const poolRes = await db.collection('matching_pool')
      .where({ expireAt: _.gte(now) })
      .get();

    const pool = poolRes.data || [];
    if (!pool.length) {
      console.log('matching_pool 当前无可用记录');
      return ok('无可匹配记录', { cleanedExpired, totalPicked: 0, matchedCount: 0 });
    }

    totalPicked = pool.length;
    console.log(`matching_pool 可用记录: ${totalPicked} 条`);

    // 2) 按 timeSlotKey 分组
    const groups = groupBy(pool, x => x.timeSlotKey);

    // 3) 分组配对
    for (const timeSlotKey of Object.keys(groups)) {
      const users = groups[timeSlotKey].slice(); // 浅拷贝
      if (users.length < 2) continue;

      // 解析时间段（从 key 中提取 HH:mm-HH:mm）
      const { startTime, endTime } = parseTimeSlotKey(timeSlotKey);

      // 简单两两配对
      for (let i = 0; i + 1 < users.length; i += 2) {
        const a = users[i];
        const b = users[i + 1];

        // 选择较小的时长，避免一方时长不足
        const duration = pickDuration(a, b);

        try {
          const { created } = await createStudyPair(a, b, { startTime, endTime, duration });
          // 从池子删除
          await Promise.all([
            db.collection('matching_pool').doc(a._id).remove(),
            db.collection('matching_pool').doc(b._id).remove()
          ]);
          matchedCount += created;
          console.log(`匹配成功: ${a.userId} ⇄ ${b.userId} @ ${timeSlotKey}, 创建学习记录 ${created} 条`);
        } catch (err) {
          console.error('配对写入失败（跳过本对）:', err);
        }
      }
    }

    return ok('批量匹配完成', { cleanedExpired, totalPicked, matchedCount });
  } catch (error) {
    console.error('批量匹配处理出错:', error);
    return fail('批量匹配处理失败', error);
  }
};

// === 工具函数 ===

function ok(message, data) {
  return { code: 0, message, data };
}

function fail(message, error) {
  return { code: 500, message, error: error && error.message ? error.message : String(error) };
}

function groupBy(arr, keyGetter) {
  const map = {};
  for (const item of arr) {
    const key = keyGetter(item);
    if (!map[key]) map[key] = [];
    map[key].push(item);
  }
  return map;
}

/**
 * 从 timeSlotKey 解析出 HH:mm-HH:mm
 * - 同天: YYYY-MM-DD_HH:mm-HH:mm
 * - 跨天: YYYY-MM-DD_HH:mm-YYYY-MM-DD_HH:mm
 */
function parseTimeSlotKey(key) {
  const str = String(key || '');
  // 取最后一段的 HH:mm-HH:mm
  const seg = str.split('_').pop() || '';
  // 可能是 HH:mm-HH:mm 或 YYYY-MM-DD HH:mm（但按生成逻辑，这里是 HH:mm-HH:mm）
  if (seg.includes('-')) {
    const parts = seg.split('-');
    const left = parts[0];
    const right = parts[1];
    const startTime = left.includes(':') ? left : (left.split('_').pop() || left);
    const endTime = right.includes(':') ? right : (right.split('_').pop() || right);
    return { startTime, endTime };
  }
  // 兜底：返回默认时段
  return { startTime: '20:00', endTime: '21:00' };
}

/**
 * 选择配对时长：两者较小者
 */
function pickDuration(a, b) {
  const da = Number(a.studyDuration) || 0;
  const dbv = Number(b.studyDuration) || 0;
  if (da && dbv) return Math.min(da, dbv);
  return da || dbv || 60;
}

/**
 * 为一对用户创建两条 study_records（共享 matchId）
 * - 优先使用 matching_pool 中的 userInfo 快照
 * - 若缺失则回退默认
 */
async function createStudyPair(a, b, { startTime, endTime, duration }) {
  const now = new Date();
  const matchId = `match_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;

  const aInfo = normalizeUserInfo(a.userInfo, a.userId);
  const bInfo = normalizeUserInfo(b.userInfo, b.userId);

  const addA = db.collection('study_records').add({
    data: {
      userId: a.userId,
      matchId,
      partnerId: b.userId,
      startTime,
      endTime,
      duration,
      status: 'not_started',
      createTime: now,
      updateTime: now,
      partnerInfo: bInfo,
      actualStartTime: null,
      actualEndTime: null,
      actualDuration: 0,
      breakCount: 0,
      focusScore: 0
    }
  });

  const addB = db.collection('study_records').add({
    data: {
      userId: b.userId,
      matchId,
      partnerId: a.userId,
      startTime,
      endTime,
      duration,
      status: 'not_started',
      createTime: now,
      updateTime: now,
      partnerInfo: aInfo,
      actualStartTime: null,
      actualEndTime: null,
      actualDuration: 0,
      breakCount: 0,
      focusScore: 0
    }
  });

  const [ra, rb] = await Promise.all([addA, addB]);
  return { created: (ra && ra._id ? 1 : 0) + (rb && rb._id ? 1 : 0), matchId };
}

function normalizeUserInfo(info, openId) {
  const safe = info || {};
  return {
    nickName: safe.nickName || '学习伙伴',
    avatarUrl: safe.avatarUrl || '/assets/icons/avatar-placeholder.png',
    openId
  };
}